#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMessageBox>
#include <QFileDialog>
#include <QDateTime>
#include <QTextCursor>
#include <QScrollBar>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , m_bootloader(new Bootloader(this))
    , m_progressDialog(nullptr)
    , m_configParser(new ConfigParser)
{
    ui->setupUi(this);
    setupUI();
    setupConnections();
    updatePortInfo();

    // 从配置文件读取默认的待烧录固件的文件路径
    QString settingFilePath = defaultSettingFilePath();
    m_configParser->loadConfig(settingFilePath);
    m_currentFile = m_configParser->getTargetObjPath();
    ui->filePathLineEdit->setText(m_currentFile);

    // 初始化连接状态为断开
    updateConnectionStatus(false);

    appendLog("MCU Bootloader GUI 已启动");
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setupUI()
{
    // 设置窗口标题和大小
    setWindowTitle("MCU Bootloader - Qt6");
    resize(1000, 700);

    // 设置日志文本框为只读
    ui->logTextEdit->setReadOnly(true);

    // 初始化状态指示灯为灰色（未连接状态）
    updateConnectionStatus(false);

    // 初始化进度对话框
    m_progressDialog = new QProgressDialog(this);
    m_progressDialog->setWindowTitle("编程进度");
    m_progressDialog->setLabelText("正在编程...");
    m_progressDialog->setCancelButtonText("取消");
    m_progressDialog->setMinimum(0);
    m_progressDialog->setMaximum(100);
    m_progressDialog->setValue(0);
    m_progressDialog->close();
}

void MainWindow::setupConnections()
{
    // 按钮连接
    connect(ui->refreshPortsButton, &QPushButton::clicked,
            this, &MainWindow::onRefreshPortsClicked);
    connect(ui->connectButton, &QPushButton::clicked,
            this, &MainWindow::onConnectClicked);

    connect(ui->openFileButton, &QPushButton::clicked,
            this, &MainWindow::onOpenFileClicked);
    connect(ui->programButton, &QPushButton::clicked,
            this, &MainWindow::onProgramClicked);
    connect(ui->eraseButton, &QPushButton::clicked,
            this, &MainWindow::onEraseClicked);
    connect(ui->resetButton, &QPushButton::clicked,
            this, &MainWindow::onResetClicked);

    // 日志按钮连接
    connect(ui->clearLogButton, &QPushButton::clicked,
            this, [this]() {
                ui->logTextEdit->clear();
                appendLog("日志已清空");
            });
    connect(ui->saveLogButton, &QPushButton::clicked, this, [this]() {
        QString fileName = QFileDialog::getSaveFileName(
            this,
            "保存日志",
            QString("bootloader_log_%1.txt")
                .arg(QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss")),
            "文本文件 (*.txt)"
            );
        if (!fileName.isEmpty()) {
            QFile file(fileName);
            if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
                file.write(ui->logTextEdit->toPlainText().toUtf8());
                file.close();
                appendLog("日志已保存: " + fileName);
            } else {
                appendLog("保存日志失败", true);
            }
        }
    });

    // Bootloader信号连接
    connect(m_bootloader, &Bootloader::progressUpdated,
            this, &MainWindow::handleBootloaderProgress);
    connect(m_bootloader, &Bootloader::operationFinished,
            this, &MainWindow::handleBootloaderFinished);
    connect(m_bootloader, &Bootloader::errorOccurred,
            this, &MainWindow::handleBootloaderError);
    connect(m_bootloader, &Bootloader::logMessage,
            this, &MainWindow::handleBootloaderLog);
}

void MainWindow::updateConnectionStatus(bool connected)
{
    if (connected) {
        // 连接状态 - 绿色圆形
        ui->statusIndicator->setStyleSheet(
            "QLabel#statusIndicator {"
            "   border: 2px solid darkgreen;"
            "   border-radius: 10px;"
            "   background-color: limegreen;"
            "}"
            );
        ui->statusLabel->setText("已连接");
        ui->connectButton->setText("断开");

        // 连接成功后启用操作按钮
        ui->programButton->setEnabled(true);
        ui->eraseButton->setEnabled(true);
        ui->resetButton->setEnabled(true);
    } else {
        // 断开状态 - 灰色圆形
        ui->statusIndicator->setStyleSheet(
            "QLabel#statusIndicator {"
            "   border: 2px solid gray;"
            "   border-radius: 10px;"
            "   background-color: lightgray;"
            "}"
            );
        ui->statusLabel->setText("未连接");
        ui->connectButton->setText("连接");

        // 断开连接后禁用操作按钮
        ui->programButton->setEnabled(false);
        ui->eraseButton->setEnabled(false);
        ui->resetButton->setEnabled(false);
    }
}

void MainWindow::updatePortInfo()
{
    ui->portComboBox->clear();

    // 获取所有可用串口
    const auto ports = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &port : ports) {
        QString portInfo = QString("%1 - %2")
        .arg(port.portName(), port.description());
        ui->portComboBox->addItem(portInfo, port.portName());
    }

    if (ports.isEmpty()) {
        ui->portComboBox->addItem("未找到串口");
        ui->connectButton->setEnabled(false);
    } else {
        ui->connectButton->setEnabled(true);
    }
}

void MainWindow::appendLog(const QString &message, bool isError)
{
    QString timestamp = QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
    QString logMessage = QString("[%1] %2").arg(timestamp, message);

    QTextCursor cursor(ui->logTextEdit->textCursor());
    cursor.movePosition(QTextCursor::End);

    QTextCharFormat format;
    if (isError) {
        format.setForeground(Qt::red);
        format.setFontWeight(QFont::Bold);
    } else {
        format.setForeground(Qt::black);
    }

    cursor.setCharFormat(format);
    cursor.insertText(logMessage + "\n");

    // 自动滚动到底部
    QScrollBar *scrollBar = ui->logTextEdit->verticalScrollBar();
    scrollBar->setValue(scrollBar->maximum());
}

void MainWindow::onRefreshPortsClicked()
{
    updatePortInfo();
    appendLog("已刷新串口列表");
}

void MainWindow::onConnectClicked()
{
    // 如果当前按钮文字是"断开"，则执行断开操作
    if (ui->connectButton->text() == "断开") {
        m_bootloader->disconnectSerial();
        appendLog("已断开串口连接");
        updateConnectionStatus(false);
        return;
    }

    // 否则执行连接操作
    if (ui->portComboBox->currentData().isNull()) {
        QMessageBox::warning(this, "警告", "请选择有效的串口");
        return;
    }

    QString portName = ui->portComboBox->currentData().toString();
    int baudRate = ui->baudRateComboBox->currentText().toInt();

    appendLog(QString("尝试连接串口: %1, 波特率: %2").arg(portName).arg(baudRate));

    if (m_bootloader->connectSerial(portName, baudRate)) {
        appendLog(QString("已连接到串口: %1, 波特率: %2").arg(portName).arg(baudRate));
        updateConnectionStatus(true);
    } else {
        appendLog("连接失败", true);
        // 连接失败时保持灰色状态，按钮文字不变
        updateConnectionStatus(false);
    }
}

void MainWindow::onOpenFileClicked()
{
    QString fileName = QFileDialog::getOpenFileName(
        this,
        "选择固件文件",
        "",
        "二进制文件 (*.bin *.hex *.s19);;所有文件 (*.*)"
        );

    if (!fileName.isEmpty()) {
        m_currentFile = fileName;
        ui->filePathLineEdit->setText(fileName);

        QFileInfo fileInfo(fileName);
        QString fileSize = QString::number(fileInfo.size());

        appendLog(QString("已选择文件: %1").arg(fileName));
        appendLog(QString("文件大小: %1 字节").arg(fileSize));

        // 选择文件后启用编程按钮（如果已连接）
        if (m_bootloader->isConnected()) {
            ui->programButton->setEnabled(true);
        }
    }
}

void MainWindow::onProgramClicked()
{
    if (m_currentFile.isEmpty()) {
        QMessageBox::warning(this, "警告", "请先选择固件文件");
        return;
    }

    if (!m_bootloader->isConnected()) {
        QMessageBox::warning(this, "警告", "请先连接串口");
        return;
    }

    QFileInfo fileInfo(m_currentFile);
    if (!fileInfo.exists()) {
        QMessageBox::warning(this, "警告", "固件文件不存在");
        return;
    }

    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        "确认编程",
        QString("确定要编程设备吗？\n文件: %1\n大小: %2 字节")
            .arg(fileInfo.fileName())
            .arg(fileInfo.size()),
        QMessageBox::Yes | QMessageBox::No
        );

    if (reply == QMessageBox::Yes) {
        m_progressDialog->show();
        m_bootloader->programDevice(m_currentFile);
    }
}

void MainWindow::onEraseClicked()
{
    if (!m_bootloader->isConnected()) {
        QMessageBox::warning(this, "警告", "请先连接串口");
        return;
    }

    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        "确认擦除",
        "确定要擦除设备吗？",
        QMessageBox::Yes | QMessageBox::No
        );

    if (reply == QMessageBox::Yes) {
        m_bootloader->eraseDevice();
    }
}

void MainWindow::onResetClicked()
{
    if (!m_bootloader->isConnected()) {
        QMessageBox::warning(this, "警告", "请先连接串口");
        return;
    }

    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        "确认重置",
        "确定要重置设备吗？",
        QMessageBox::Yes | QMessageBox::No
        );

    if (reply == QMessageBox::Yes) {
        m_bootloader->resetDevice();
    }
}

void MainWindow::handleBootloaderProgress(int progress, const QString &message)
{
    m_progressDialog->setValue(progress);
    m_progressDialog->setLabelText(message);
    appendLog(QString("进度: %1% - %2").arg(progress).arg(message));
}

void MainWindow::handleBootloaderFinished(bool success, const QString &message)
{
    m_progressDialog->close();

    if (success) {
        appendLog("操作完成: " + message);
        QMessageBox::information(this, "成功", message);
    } else {
        appendLog("操作失败: " + message, true);
        QMessageBox::critical(this, "错误", message);
    }
}

void MainWindow::handleBootloaderError(const QString &error)
{
    appendLog("错误: " + error, true);
    m_progressDialog->close();

    // 如果发生串口错误，自动断开连接
    if (m_bootloader->isConnected()) {
        m_bootloader->disconnectSerial();
        updateConnectionStatus(false);
        appendLog("由于错误，已自动断开串口连接");
    }

    QMessageBox::critical(this, "错误", error);
}

void MainWindow::handleBootloaderLog(const QString &message)
{
    appendLog(message);
}

